Skip to content

fix(pack): exclude existing package.json from assets - #36507

Open
rathodkunj2005 wants to merge 2 commits into
denoland:mainfrom
rathodkunj2005:fix/pack-duplicate-package-json
Open

rathodkunj2005 wants to merge 2 commits into
denoland:mainfrom
rathodkunj2005:fix/pack-duplicate-package-json

Conversation

@rathodkunj2005

Copy link
Copy Markdown
Contributor

Fixes #36387.

When deno pack collects non-module assets, it now excludes a root package.json because the pack pipeline already writes a generated package.json to the same tar path. This prevents tarballs from containing two entries named package/package.json.

The existing package JSON spec fixture now includes a source package.json and verifies both that it is not counted as an asset and that the archive contains exactly one generated package JSON entry.

Verification

  • CARGO_INCREMENTAL=0 cargo test -p specs_tests --test specs package_json_content -- --nocapture — 1 test passed
  • ./tools/lint.js cli/tools/pack/mod.rs — passed
  • cargo fmt --check -p deno — passed
  • target/debug/deno fmt --check tests/specs/pack/package_json_content/__test__.jsonc tests/specs/pack/package_json_content/package.json — checked 2 files

@MILLERMARRU MILLERMARRU left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked package_dir resolves to package.config_file.dir_path(), the actual source root, so package_dir.join("package.json") is exactly the path a hand-written package.json sitting next to deno.json would have, and exactly where the generated one gets written too. Before this, only the config file itself (deno.json) was excluded from the generic asset-collection pass, so an existing package.json in the source tree would get swept up as a regular asset and end up in the tarball alongside the generated one under the same path, a real duplicate-entry problem, not just wasted bytes.

Good that this is scoped to package_dir.join("package.json") specifically rather than excluding package.json anywhere in the tree, a nested one inside a subdirectory (a bundled sub-package, say) is a different file and has no reason to be swept up by this exclusion.

The test change checking grep -c '^package/package.json$' equals exactly 1 in the resulting tarball is the right assertion, it directly verifies the duplicate is gone rather than just checking the command exits successfully, and the 0 assets collected expectation confirms the source package.json is no longer being counted as a collected asset at all.

@bartlomieju bartlomieju left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right fix for #36387. A tar with two package/package.json members of differing content is genuinely broken — which one you get depends on the extractor, and npm/tar take last-wins, so the source file was silently overriding the generated manifest for consumers.

The existing exclusion only covered package.config_file.specifier, which is deno.json in the case that regressed; adding the explicit root package.json covers the sibling case and is a no-op when the config file already is package.json. Scoping it to package_dir.join(...) rather than any package.json is right too — nested ones don't collide and should still ship.

The test is better than it needs to be: 0 assets collected pins that the file isn't merely deduplicated later but never collected, and grep -c '^package/package.json$' catches a regression that a cat of the extracted file would sail straight past.

The test node_compat failure is test-cluster-concurrent-disconnect.js, unrelated to pack.

One thing for a follow-up issue rather than this PR: silently dropping the source package.json means any fields in it that the generated manifest doesn't reproduce (custom scripts, engines, and so on) vanish from the published tarball without a word. Strictly better than shipping two conflicting files, but a note in the pack output — or merging unknown fields — might be worth considering. LGTM.

@CLAassistant

CLAassistant commented Sep 23, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

deno pack in project with a package.json file produces tarball with two package.json files

4 participants